﻿
using Mapster;
using RsCms.Application.User.Dto;
using RsCms.Core.User.Aggregate.Entities;
using RsCode;
using RsCode.AspNetCore.Jwt;
using RsCode.Domain;
using Rswl.Common.Application.User.Dto;
using Rswl.Common.Core;
using Rswl.Common.Core.User.Aggregate.Entities;
using Rswl.Common.Core.User.Aggregate.ValueObject;

namespace Rswl.Common.Application.User
{
    public class UserAppService : IUserAppService
    {
        IUserRepository userRepository;
        IUserDomainService userDomainService;
        IRepository<UserRoleInfo> userRoleRepository;
      
        public UserAppService(
            IUserRepository _userRepository, 
            IRepository<UserRoleInfo> userRoleRepository,
            IUserDomainService _userDomainService
          )
        { 
            userRepository = _userRepository; 
            userDomainService = _userDomainService; 
            this.userRoleRepository= userRoleRepository;
        }
		public UserRoleEditDto SaveUserRole(UserRoleEditDto dto)
        {
            var info = dto.Adapt<UserRoleInfo>();
            info=userRoleRepository.InsertOrUpdate(info);
            return info.Adapt<UserRoleEditDto>();
        }

		public void DeleteUserRole(long userRoleId)
        {
            userRoleRepository.Delete(x=>x.Id==userRoleId);
        }

		public async Task<AccessTokenInfo> PasswordRegisterAsync(PasswordRegiserDto dto)
        {
            await userDomainService.CheckOpenRegisterAsync();
            var user= await userDomainService.PasswordRegisterAsync(dto.Adapt<PasswordRegisterValueObject>());
            return userDomainService.CreateUserAccessToken(user);
        }
        public async Task<AccessTokenInfo> PhoneRegisterAsync(PhoneRegisterDto dto)
        {
			await userDomainService.CheckOpenRegisterAsync();
			var user = await userDomainService.PhoneRegisterAsync(dto.Adapt<PhoneRegisterValueObject>());
            return userDomainService.CreateUserAccessToken(user);
        }
        public async Task<AccessTokenInfo> PasswordLoginAsync(PasswordLoginDto dto)
        {
            var user = await userDomainService.PasswordLoginAsync(dto.Adapt<PasswordLoginValueObject>());
            return userDomainService.CreateUserAccessToken(user);
        }
        public async Task ChangeLoginPasswordAsync(PasswordChangeDto dto)
        {
            var user = userDomainService.GetLoginUserInfo("");
            if(string.IsNullOrWhiteSpace(user.UserId))
            {
                throw new AppException("请重新登录后重试");
            }
            await userDomainService.ChangePasswordAsync(user.UserId, dto.Password);
        }
        public async Task<UserInfoDto> GetLoginUserInfoAsync(string appId = "")
        {
            var userInfo =  userDomainService.GetLoginUserInfo(appId);
            var dto= userInfo.Adapt<UserInfoDto>();
            var shareInfo = await GetShareInfoAsync(userInfo.UserId);
            dto.ShareInfo = shareInfo;
            dto.InviteCode = shareInfo?.InviteCode??"";
            
            return dto;
        }
        public async Task<AccessTokenInfo> WechatLoginAsync(WechatLoginDto dto)
        {
            var user = await userDomainService.OtherAuthUserLoginAsync(dto.Adapt<OtherAuthUserValueObject>());
            return userDomainService.CreateUserAccessToken(user);
        }
        public async Task<string> FindPasswordAsync(PasswordFindDto dto)
        {
            return await userDomainService.FindPasswordAsync(dto.Adapt<PasswordFindValueObject>());
        }

        public async Task ChangeRoleAsync(RoleChangeDto dto)
        {
            await userDomainService.ChangeRoleAsync(dto.Adapt<ChangeUserRole>());
        }

        public async Task<PageData<UserInfoDto>> PageUserInfoAsync(int page, int pageSize)
        {
            var select=userRepository.Select.Page(page, pageSize).OrderByDescending(x=>x.RegisterDate);
             var info=await userRepository.PageAsync(page, pageSize,select);
            return info.Adapt<PageData<UserInfoDto>>();
        }

        public async Task<AccessTokenInfo> SmsLoginAsync(SmsLoginDto dto)
        {
            var user = await userDomainService.SmsLoginAsync(dto.Phone, dto.Sms);
            return userDomainService.CreateUserAccessToken(user);
        }

        public async Task<PageData<UserInfoDto>> PageInviteUserAsync(int page,int pageSize)
        {
            var user = userDomainService.GetLoginUserInfo("");
            if(string.IsNullOrEmpty(user.UserId))
            {
                throw new AppException(401,"未授权");
            }

            var select=userRepository.Select.Page(page,pageSize).Where(x=>x.InviteUserId == user.UserId).OrderByDescending(x=>x.RegisterDate);
            var list =await userRepository.PageAsync(page, pageSize);
            return list.Adapt<PageData<UserInfoDto>>();
        }

        public async Task<PageData<UserGradeDto>>PageUserGradeInfoAsync(int page,int pageSize)
        {
            var info =await userRepository.UserGradeRepository.PageAsync(page, pageSize);
            return info.Adapt<PageData<UserGradeDto>>();
        }

        public void SaveUserGrade(UserGradeDto grade)
        {
            var info = grade.Adapt < UserGradeInfo > ();
            userRepository.UserGradeRepository.InsertOrUpdate(info);
        }

        public async Task AdminCreateAccountAsync(AccountCreateDto dto)
        {
            var value = new PasswordRegisterValueObject
			{
                UserRoles =dto.Roles,
                 UserId=dto.UserId,
                 Password1=dto.Password1,
                  Password2=dto.Password1,
                   UserName=dto.UserName,
                   Phone=dto.Phone,
                   TrueName=dto.TrueName,
            };
			var user = await userDomainService.PasswordRegisterNoCheckAsync(value);
			
		}















        public async Task<UserInfoDto> GetUserAsync(string userId,string appId="")
        {
            if(string.IsNullOrWhiteSpace(userId))
            {
                throw new AppException(401,"请重新登录");
            }
            UserInfoDto dto = new UserInfoDto();
            var user = await userRepository.GetUserInfoAsync(userId);
            if(user==null)
            {
                return null;
            }
            dto = user.Adapt<UserInfoDto>();
            //获取微信OpenId
            var ext = await userRepository.GetExtInfosAsync(userId);
            if(string.IsNullOrEmpty(appId))
            {
                dto.OpenId = ext?.FirstOrDefault()?.OpenId ?? "";
            }else
            {
                dto.OpenId = ext?.FirstOrDefault(x => x.AppId == appId)?.OpenId ?? "";
            }
            var shareInfo = await userRepository.GetShareInfoAsync(userId);
            dto.InviteCode= shareInfo?.InviteCode??"";
            return dto;
        }

        public async Task<UserInfoDto> GetOrCreateUserAsync(UserAuthInfoDto dto)
        {
            var value = dto.Adapt<OAuthUserValueObject>();
            var user = await userDomainService.GetOrCreateUserAysnc(value);
            return user.Adapt<UserInfoDto>();
        }

        public  Task<AccessTokenInfo> PhoneLogin(PhoneLoginDto dto)
        {
            throw new NotImplementedException();
        }

        public async Task<List<UserInfoDto>> GetAdminListAsync()
        {
            var info = await userRepository.GetAdminAsync();
            if (info != null)
            {
                return info.Adapt<List<UserInfoDto>>();
            }
            return null;
        }

        public  Task<AccessTokenInfo> UserLogin(UserLoginDto dto)
        {
            throw new NotImplementedException();
        }

        

        public async Task<AccessTokenInfo> AdminLoginAsync(PasswordLoginDto dto)
        {
            return await userDomainService.AdminLoginAsync(dto.Adapt<PasswordLoginValueObject>()); 
        }

        public async Task<PageData<UserInfoDto>>GetPageUserAsync(int page)
          {
            var info = await userRepository.GetPageAsync(page, 20);
            return info.Adapt<PageData<UserInfoDto>>();
            }

        public async Task<PageData<UserInfoDto>> PageFansAsync(int page,int pageSize,string userId)
        {
            var info = await userRepository.PageFansAsync(page,pageSize,userId);
            return info.Adapt<PageData<UserInfoDto>>();
        }

        public async Task SetAdminAsync(string userId)
        {
            var info = await userRepository.GetUserInfoAsync(userId);
            if (info == null)
                throw new AppException("指定用户无效");
            info.ChangeRole(UserRole.Admin);
            await userRepository.SaveAsync(info);
        }

        public async Task CancelAdminAsync(string userId)
        {
            var info = await userRepository.GetUserInfoAsync(userId);
            if (info == null)
                throw new AppException("指定用户无效");
            info.ChangeRole(UserRole.Member);
            await userRepository.SaveAsync(info);
        }

        public async Task<List<ShippingAddressDto>>GetShippingAddressesAsync(string userId)
        {
            var info = await userRepository.GetShippingAddressAsync(userId);
            return info.Adapt<List<ShippingAddressDto>>();
        }

        public async Task<long>SaveShippingAddressAsync(string userId,ShippingAddressEditDto dto)
        {
            var info = dto.Adapt<ShippingAddressInfo>();
            return await userDomainService.SaveShippingAddressAsync(userId, info);
        }
        public async Task RemoveShippingAddressAsync(string userId,long addressId)
        {
            await userDomainService.RemoveShippingAddressAsync(userId, addressId);
        }

        public async Task BindInviteCodeAsync(string userId,string inviteCode)
        {
            await userDomainService.BindInviteCode(userId, inviteCode); 
        }

        public async Task<ShareInfoDto>GetShareInfoAsync(string userId)
        {
            if(string.IsNullOrWhiteSpace(userId))
            {
                ShareInfoDto dto = new ShareInfoDto();
                return dto;
            }
            var info = await userRepository.GetShareInfoAsync(userId);
            if(info==null)
            {
                info = new ShareInfo(userId, "");
                await userRepository.SaveAsync(info);
            }
            return info.Adapt<ShareInfoDto>();
        }

       
        public async Task ChangeGradeAsync(string userId, UserGrade grade, int days)
        {
           await userDomainService.ChangeUserGradeAsync(userId, grade);
        }
        public async Task<List<UserExtInfo>> GetExtInfoAsync(string userId)
        {
            return await userRepository.GetExtInfosAsync(userId);
        }

        /// <summary>
        /// 推广VIP奖励额度
        /// </summary>
        /// <param name="userGrade"></param>
        /// <param name="invoteGrade"></param>
        /// <returns></returns>
        public int InvoteVipAwardAmount(UserGrade userGrade,UserGrade invoteGrade)
        {
            int goldAmount = 0;

            //推广VIP1奖励
            if (invoteGrade==UserGrade.VIP1)
            {
                if(userGrade== UserGrade.Member)
                {
                    goldAmount = 20000;
                }
                if (userGrade == UserGrade.VIP1)
                {
                    goldAmount = 100000;
                }
                if (userGrade == UserGrade.VIP2)
                {
                    goldAmount = 190000;
                }
                if (userGrade == UserGrade.VIP5)
                {
                    goldAmount = 190000;
                }
            }
            //推广VIP2奖励
            if (invoteGrade==UserGrade.VIP2)
            {
                if (userGrade == UserGrade.Member)
                {
                    goldAmount = 50000;
                }
                if (userGrade == UserGrade.VIP1)
                {
                    goldAmount = 250000;
                }
                if (userGrade == UserGrade.VIP2)
                {
                    goldAmount = 350000;
                }
                if (userGrade == UserGrade.VIP5)
                {
                    goldAmount = 450000;
                }
            }
            //推广VIP5奖励
            if (invoteGrade== UserGrade.VIP5)
            {
                if (userGrade == UserGrade.Member)
                {
                    goldAmount = 100000;
                }
                if (userGrade == UserGrade.VIP1)
                {
                    goldAmount = 1000000;
                }
                if (userGrade == UserGrade.VIP2)
                {
                    goldAmount = 1400000;
                }
                if (userGrade == UserGrade.VIP5)
                {
                    goldAmount = 1500000;
                }
            }
             
 
            return goldAmount;
        }

        public decimal IntegralPrice(UserGrade Grade,long integralAmount)
        {
            //原价
            decimal price = decimal.Round((decimal)integralAmount / 10,2);  

            int discount=GetIntegralDiscount(Grade);
            return integralPrice(price, discount);
        }


        /// <summary>
        /// 获取积分价格信息
        /// </summary>
        /// <returns></returns>
        public object GetIntegralPriceInfo(int userGrade)
        {
            int discount = 0;// GetIntegralDiscount(userGrade);
            object[] items = new object[]{
                new {
                  name="100积分",
                  old_price=10,
                  pay_amount=integralPrice(10,discount),
                  integral_amount=100,
                },
                new {
                  name="200积分",
                  old_price=20,
                  pay_amount=integralPrice(20,discount),
                  integral_amount=200,
                },
                new {
                  name="500积分",
                  old_price=50,
                  pay_amount=integralPrice(50,discount),
                  integral_amount=500,
                },
                new {
                  name="1000积分",
                  old_price=100,
                  pay_amount=integralPrice(100,discount),
                  integral_amount=1000,
                },
                new {
                  name="5000积分",
                  old_price=500,
                  pay_amount=integralPrice(500,discount),
                  integral_amount=5000,
                }
            };

            //string remark = $"你是{userGrade.ToDescription()},享有{discount}折优惠";
            //if (userGrade == UserGrade.Member)
            //{
            //    remark = "升级VIP后享受优惠";
            //}

            string remark = "";
            return new
            {
                price_items = items,
                remark = remark,
                desc_items = new string[]
              {
                  "积分充值优惠折扣",
                     $"VIP1独享{GetIntegralDiscount(UserGrade.VIP1)}折优惠",
                     $"VIP2独享{GetIntegralDiscount(UserGrade.VIP2)}折优惠",
                     $"VIP5独享{GetIntegralDiscount(UserGrade.VIP5)}折优惠",
              }
            };
        }


        int GetIntegralDiscount(UserGrade userGrade)
        {
            int discount = 0;
            if (userGrade == UserGrade.VIP1)
            {
                discount = 8;
            }

            if (userGrade == UserGrade.VIP2)
            {
                discount = 6;
            }

            if (userGrade == UserGrade.VIP5)
            {
                discount = 5;
            }
            return discount;
        }

        decimal integralPrice(decimal oldprice,int discount)
        { 
            if (discount <= 0) return oldprice; 
            return decimal.Round(oldprice * discount / 10, 2);
        }

        public async Task<UserInfoDto> ChangeUserInfoAsync(string userId,ChangeUserInfoDto dto)
        {
            var changeInfo = new ChangeUserInfo(userId, dto.UserName, dto.HeaderImage);
            var user = await userDomainService.ChangeAvatarAsync(changeInfo);
            return user.Adapt<UserInfoDto>();
        }

       public async Task ChangeAccountStatusAsync(AccountStatusEditDto dto)
        {
            await userDomainService.ChangeSatusAsync(dto.UserId, dto.Status);
        }

        
    }
}
